//
//  closureVC.swift
//  swiftDemo
//
//  Created by yaqiang bi on 2017/3/15.
//  Copyright © 2017年 毕小强. All rights reserved.
//
/**
 *
 * ......................我佛慈悲......................
 *                       _oo0oo_
 *                      o8888888o
 *                      88" . "88
 *                      (| -_- |)
 *                      0\  =  /0
 *                    ___/`---'\___
 *                  .' \\|     |// '.
 *                 / \\|||  :  |||// \
 *                / _||||| -卍-|||||- \
 *               |   | \\\  -  /// |   |
 *               | \_|  ''\---/''  |_/ |
 *               \  .-\__  '-'  ___/-. /
 *             ___'. .'  /--.--\  `. .'___
 *          ."" '<  `.___\_<|>_/___.' >' "".
 *         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 *         \  \ `_.   \_ __\ /__ _/   .-` /  /
 *     =====`-.____`.___ \_____/___.-`___.-'=====
 *                       `=---='
 *
 *..................佛祖开光 ,永无BUG...................
 *
 *          闭包,干巴爹
 *
 */
import UIKit

class closureVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.white
        
        /*
         *  排序闭包
         **/
        func backward (_ s1:String,_ s2:String) -> Bool{
            return s1 > s2
        }
        let names = ["Chris","Alex","Ewa","Barry","Daniella"]
        let newName = names.sorted(by: backward)
        print(newName)
        
        let newsetnames = names.sorted(by: {(s1:String,s2:String)->Bool in return s1 < s2})
        print(newsetnames)
        let names1 = names.sorted(by: {s1,s2 in return s1 > s2})
        print(names1)
        let names2 = names.sorted(by: {s1,s2 in s1<s2})
        print(names2)
        let names3 = names.sorted(by: {$0 > $1})
        print(names3)
        let names4 = names.sorted(by: <)
        print(names4)
        
        let digitNames =  [
            0: "Zero",1: "One",2: "Two",  3: "Three",4: "Four",
            5: "Five",6: "Six",7: "Seven",8: "Eight",9: "Nine"
        ]
        let numbers  = [16,58,510]
        let strings = numbers.map { (number) -> String in
            var number = number
            var output = ""
            repeat {
                output = digitNames[number%10]! + output
                number /= 10
            }while number > 0
            return output
        }
        print(strings)
        
        someFunctionThatTakesAClosure { (s1, s2) -> Bool in
            return s1 > s2
        }
        
       let str1 = map { (s1) -> String in
            var s1 = s1
            var output = ""
            repeat {
                output = digitNames[s1%10]! + output
                s1 /= 10
            }while s1 > 0
            return output
        }
        print(str1)
        
        let increment = makeIncrementer(forIncrement: 1)
        print(increment())
        print(increment())
        
        
        /// 闭包逃逸
        var completionHandlers:[()->Void] = []
        func someFunctionWithEscapingClosure(completionHandler:@escaping ()->Void){
            completionHandlers.append(completionHandler)
        }
        func sonmeFunctionWithNonescapingClosure(closure:()->Void){
            closure()
        }
    /*
        class SomeClass{
            var x = 10
            func doSomething()  {
                someFunctionWithEscapingClosure {
                    self.x = 100
                }
                sonmeFunctionWithNonescapingClosure {
                    x = 200
                }
            }
            
        }
        let instance = SomeClass()
        instance.doSomething()
        print(instance.x)
        
        completionHandlers.first?()
        print(instance.x)
        */
        
        
        /*
         *          自动闭包
         **/
        var customersInLine = ["Chris","Alex","Ewa","Barry","Daniella","Ajxa","swift"]
        print(customersInLine.count)
        
        let customerProvider = {customersInLine.remove(at: 0)}
        print(customersInLine.count)
        
        print("Now serving \(customerProvider())")
        print(customersInLine.count)
        
        func serve(customer customerProvider:()->String){
            print("Now serving \(customerProvider())")
        }
        serve(customer: {customersInLine.remove(at: 0)})
        
        func serve1(customer customerProvider:@autoclosure ()->String){
            print("Now serving \(customerProvider())")
        }
        serve1(customer: customersInLine.remove(at: 0))
        
        var customerProviders : [()->String] = []
        func collectCustomerProviders(_ customerProvider:@autoclosure @escaping ()->String){
            customerProviders.append(customerProvider)
        }
        collectCustomerProviders(customersInLine.remove(at: 0))
        collectCustomerProviders(customersInLine.remove(at: 0))
        
        print("Collecter \(customersInLine.count) closures")
        for customerProvider in customerProviders {
            print("Now serving \(customerProvider())")
        }
        print("Collecter \(customersInLine.count) closures")
        // Do any additional setup after loading the view.
    }
    
    /// 最简单闭包
    ///
    /// - Parameter closure: 尾随闭包
    func someFunctionThatTakesAClosure(closure:(_ s1:String,_ s2:String)->Bool)  {
        
    }
    
    
    /// 仿写数组map闭包
    ///
    /// - Parameter closure: 闭包
    /// - Returns: 字符串数组
    func map (_ closure:(_ s1:Int) -> String) -> [String]{
        var strMarr :[String] = []
        let arr = [111,222,333]
        for a in arr {
            strMarr.append(closure(a))
        }
        return strMarr
    }
    
    /// 捕获值
    ///
    /// - Parameter amount: 形参
    /// - Returns: 一个闭包
    func makeIncrementer(forIncrement amount:Int) -> ()->Int {
        var runningTotal = 0
        func increment()->Int{
            runningTotal += amount
            return runningTotal
        }
        return increment
    }
    

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}
